#!/usr/bin/env python3
"""
setuptools.build_meta 详解：不是函数，而是 PEP 517 构建后端接口的实现模块

这个脚本演示了 setuptools.build_meta 的本质和工作机制
"""

def explain_build_meta():
    """解释 setuptools.build_meta 的本质"""
    
    print("🔍 setuptools.build_meta 是什么？")
    print("=" * 60)
    
    print("""
setuptools.build_meta 不是一个函数，而是一个 Python 模块！

它是 setuptools 包中的一个子模块，实现了 PEP 517 定义的构建后端接口。

📁 模块层次结构：
   setuptools/              # setuptools 包
   ├── __init__.py         # 主模块
   ├── build_meta.py       # ← 这就是 setuptools.build_meta
   ├── setup.py
   └── ...

🎯 PEP 517 构建后端接口规范：
   构建后端必须提供以下标准函数：
   
   1. build_wheel(wheel_directory, config_settings=None, metadata_directory=None)
   2. build_sdist(sdist_directory, config_settings=None)
   3. get_requires_for_build_wheel(config_settings=None)
   4. get_requires_for_build_sdist(config_settings=None)
   5. prepare_metadata_for_build_wheel(metadata_directory, config_settings=None)
    """)

def show_build_meta_interface():
    """展示 setuptools.build_meta 的接口"""
    
    print("\n🛠️  setuptools.build_meta 模块接口")
    print("=" * 60)
    
    # 模拟 setuptools.build_meta 的核心接口
    interface_code = '''
# setuptools/build_meta.py (简化版)

def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
    """构建 wheel 文件"""
    # 1. 读取 pyproject.toml 配置
    # 2. 如果存在 setup.py，执行它获取动态配置
    # 3. 合并配置信息
    # 4. 构建 wheel 文件
    return wheel_filename

def build_sdist(sdist_directory, config_settings=None):
    """构建源代码分发包"""
    # 1. 收集源代码文件
    # 2. 创建 sdist tarball
    return sdist_filename

def get_requires_for_build_wheel(config_settings=None):
    """返回构建 wheel 所需的依赖"""
    # 从 pyproject.toml [build-system].requires 读取
    return ["setuptools>=64", "wheel", "cmake>=3.12"]

def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
    """准备元数据（不实际构建 wheel）"""
    # 1. 解析项目元数据
    # 2. 生成 METADATA 文件
    # 3. 返回元数据目录名
    return metadata_dir_name
    '''
    
    print(interface_code)

def show_execution_flow():
    """展示执行流程"""
    
    print("\n🔄 执行流程详解")
    print("=" * 60)
    
    print("""
当你运行 'pip install .' 或 'python -m build' 时：

1️⃣  构建工具（pip/build）读取 pyproject.toml：
    [build-system]
    build-backend = "setuptools.build_meta"
    
2️⃣  构建工具导入 setuptools.build_meta 模块：
    import setuptools.build_meta as backend
    
3️⃣  调用构建后端接口：
    # 获取构建依赖
    deps = backend.get_requires_for_build_wheel()
    
    # 准备元数据
    metadata = backend.prepare_metadata_for_build_wheel("./metadata")
    
    # 构建 wheel
    wheel_file = backend.build_wheel("./dist")

4️⃣  setuptools.build_meta 内部流程：
    a) 读取 pyproject.toml 的 [project] 部分
    b) 如果存在 setup.py，执行它：
       - 获取 ext_modules（C 扩展）
       - 获取 cmdclass（自定义构建命令）
       - 获取其他动态配置
    c) 合并所有配置
    d) 执行实际构建过程
    """)

def compare_backends():
    """比较不同的构建后端"""
    
    print("\n⚖️  不同构建后端对比")
    print("=" * 60)
    
    backends = {
        "setuptools.build_meta": {
            "描述": "setuptools 的现代构建后端",
            "优势": ["兼容传统 setup.py", "支持 C 扩展", "生态成熟"],
            "适用": "大多数 Python 包，特别是需要 C 扩展的项目"
        },
        "flit_core.buildapi": {
            "描述": "Flit 的轻量级构建后端",
            "优势": ["简单快速", "纯 Python", "配置最少"],
            "适用": "纯 Python 包，无复杂构建需求"
        },
        "poetry.core.masonry.api": {
            "描述": "Poetry 的构建后端",
            "优势": ["依赖管理强大", "现代化工具链"],
            "适用": "使用 Poetry 管理的项目"
        },
        "hatchling.build": {
            "描述": "Hatch 的构建后端",
            "优势": ["插件系统丰富", "构建钩子支持"],
            "适用": "需要复杂构建逻辑的项目"
        }
    }
    
    for backend, info in backends.items():
        print(f"\n📦 {backend}")
        print(f"   描述: {info['描述']}")
        print(f"   优势: {', '.join(info['优势'])}")
        print(f"   适用: {info['适用']}")

def show_our_project_flow():
    """展示我们项目的具体执行流程"""
    
    print("\n🏗️  我们项目的执行流程")
    print("=" * 60)
    
    print("""
在我们的项目中：

1️⃣  pyproject.toml 声明:
    build-backend = "setuptools.build_meta"

2️⃣  setuptools.build_meta 被调用后：
    
    📋 读取元数据 (from pyproject.toml):
       - name = "my-package"
       - version = dynamic (从 my_package.__version__)
       - description, authors, classifiers...
    
    🔧 执行 setup.py:
       - has_pyproject_toml() 返回 True
       - 执行最小配置的 setup():
         * ext_modules = [CMakeExtension(...)]
         * cmdclass = {'build_ext': CMakeBuild}
    
    🏭 构建过程:
       - 合并 pyproject.toml 元数据 + setup.py 扩展配置
       - 执行 CMakeBuild 来编译 C 扩展
       - 生成最终的 wheel 文件

3️⃣  关键点:
    ✓ 元数据来自 pyproject.toml (现代标准)
    ✓ C 扩展构建来自 setup.py (灵活性)
    ✓ 开发工具配置来自 pyproject.toml [tool.*]
    """)

def main():
    print("📚 setuptools.build_meta 深度解析")
    print("作者: 构建系统专家")
    
    explain_build_meta()
    show_build_meta_interface()
    show_execution_flow()
    compare_backends()
    show_our_project_flow()
    
    print(f"\n✅ 总结:")
    print("setuptools.build_meta 是一个实现了 PEP 517 标准的 Python 模块，")
    print("它提供了一套标准化的构建接口，让构建工具能够以统一的方式")
    print("构建不同的 Python 包，同时保持与传统 setup.py 的兼容性。")

if __name__ == "__main__":
    main() 